
class Hook {
    constructor(args=[]){
        this.args = args
        this.taps = [] // 将来用于存放组装好的 {}
        this._x = undefined // 将来在代码工厂函数中会给 _x = [fn1, fn2, ...]
    }

    // 接收函数名称以及函数并将参数转化为对象
    tap (options, fn){
        if(typeof options === 'string') {
            options = {
                name: options
            }
        }
        options = Object.assign({ fn }, options) // options --> {fn: ..., name: fn1}

        // 调用以下方法将组装好的 options 添加至 []
        this._insert(options)
    }

    tapAsync (options, fn){
        if(typeof options === 'string') {
            options = {
                name: options
            }
        }
        options = Object.assign({ fn }, options) 
        this._insert(options)
    }

    // 将 options的内容添加到taps中
    _insert(options){
        this.taps[this.taps.length] = options
    }

    call(...args){
        // 01 创建将来要具体执行的函数代码结构
        let callFun = this._callCreate()
        // 02 调用上述的函数并传入args
        return callFun.apply(this, args)
    }

    callAsync(...args){
        let callFun = this._callCreate()
        return callFun.apply(this, args)
    }

    _callCreate(){
        return this.compile({
            taps: this.taps,
            args: this.args
        })
    }
}

module.exports = Hook